package com.gcs.application.gui.views;

import gnu.io.CommPortIdentifier;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.LineNumberReader;
import java.net.URL;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Enumeration;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.forms.FormColors;
import org.eclipse.ui.forms.IFormColors;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.ScrolledForm;
import org.eclipse.ui.forms.widgets.Section;
import org.eclipse.ui.forms.widgets.TableWrapData;
import org.eclipse.ui.forms.widgets.TableWrapLayout;
import org.eclipse.ui.part.ViewPart;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import BISTel.PeakPerformance.SECSParser.SECSError;
import BISTel.PeakPerformance.SECSParser.SECSMessage;
import BISTel.PeakPerformance.eExecuter.Subscriber;
import BISTel.PeakPerformance.eExecuter.SECS.Device;
import BISTel.PeakPerformance.eExecuter.SECS.HSMS.HSMSMessage;
import BISTel.PeakPerformance.eExecuter.SECS.HSMS.HSMSMessageType;
import BISTel.PeakPerformance.eExecuter.SECS.secsi.SecsTimeout;

public class ConnectionView extends ViewPart implements Listener, Subscriber {

	public static Device device;

	public static final String ID = ConnectionView.class.getName();
	private Button buttonConnect;
	private Button buttonDisconnect;
	private Combo comboComport;

	// -------------------- Declare controls -----------------------
	private Combo comboProtocol;

	private Combo comboType;
	private Date date;
	private final DateFormat dateFormat = new SimpleDateFormat(
			"yyyy/MM/dd HH:mm:ss.SSS");
	private Document docConfig;

	private GridData gridDataLabel;
	private GridData gridDataLabelGroup;

	private GridData gridDataText;
	private GridData gridDataTextGroup;
	private GridLayout gridLayoutCommon;
	private HSMSMessage hsmsMessage;
	private boolean isAuto = false;
	private boolean isDataMessage;
	private String messageLog = "";
	private final int numCols = 4;
	private Object objMessage;
	private Button radioActive;
	private Button radioAuto;
	private Button radioManual;

	private Button radioPassive;

	private ScrolledForm scrolledForm;

	private SECSMessage secsMessage;
	private Section section;
	private Composite sectionClient;
	private String strConfig;
	private String strDeviceID = "";
	private String strDeviceName = "";

	private String strFileName = "";// "D:/Projects/BisTel/12s.bist.0808.0/deliverables/trunk/implementation/HSMSTestApplication/configs/configure.xml";
	private String strLogDir = "";

	private String strLogType;
	private String strPortName = "";
	private final String[] strProtocolData = { "HSMS", "SECSI" };
	private final String[] strTypeData = { "Equipment", "Host" };
	private StyleRange styleStandar, styleReceived, styleSend, styleError;
	private TableWrapData tableData;

	private TableWrapLayout tableLayout;
	private Text textDeviceID;
	private Text textIPAddress;
	private Text textLinktest;
	private Text textPort;
	private Text textT1;
	private Text textT2;
	private Text textT3;
	private Text textT4;
	private Text textT5;

	private Text textT6;
	private Text textT7;

	private Text textT8;
	/**
	 * Eclipse forms support. Requires the plug-in: org.eclipse.ui.forms
	 */
	private FormToolkit toolkit;

	private void addButton() {
		GridData gridData;
		this.toolkit.createLabel(this.sectionClient, "", SWT.NONE);

		// Create the button to connect the session.
		gridData = new GridData(GridData.HORIZONTAL_ALIGN_END);
		gridData.widthHint = 100;
		gridData.horizontalIndent = 12;

		this.buttonConnect = new Button(this.sectionClient, SWT.PUSH);
		this.buttonConnect.setText("Connect");
		this.buttonConnect.setLayoutData(gridData);
		this.buttonConnect.addSelectionListener(new SelectionListener() {
			@Override
			public void widgetDefaultSelected(final SelectionEvent e) {
			}

			@Override
			public void widgetSelected(final SelectionEvent e) {
				if (device == null) {
					if (ConnectionView.this
							.writeConfig(ConnectionView.this.docConfig)) {
						ConnectionView.this
								.writeFileConfig(ConnectionView.this.docConfig);

						// When the configuration file have changed
						ConnectionView.this.convertFileToString(new File(
								ConnectionView.this.strFileName));

						ConnectionView.this.createDevice();
					} else {
						MessageDialog.openInformation(
								ConnectionView.this.sectionClient.getShell(),
								"Information", "To check the file config.");
					}
				}
			}
		});

		// Create the button to disconnect the session.
		gridData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
		gridData.widthHint = 100;
		gridData.horizontalIndent = 12;

		this.buttonDisconnect = new Button(this.sectionClient, SWT.PUSH);
		this.buttonDisconnect.setText("Disconnect");
		this.buttonDisconnect.setLayoutData(gridData);
		this.buttonDisconnect.addSelectionListener(new SelectionListener() {
			@Override
			public void widgetDefaultSelected(final SelectionEvent e) {
			}

			@Override
			public void widgetSelected(final SelectionEvent e) {
				if (device != null) {
					// Disable connection
					device.Stop();
					device = null;

					// Write data to window and log.
					/*
					 * date = new Date(); messageLog = dateFormat.format(date) +
					 * " " + "Connection is disconnected by user. \n";
					 * createMessageLog("Disabled", null, false);
					 * 
					 * date = new Date(); messageLog = dateFormat.format(date) +
					 * " " + "Connection is in NOT CONNECTED. \n";
					 * createMessageLog("STAT@", null, false);
					 */

					ConnectionView.this.date = new Date();
					ConnectionView.this.messageLog = ConnectionView.this.dateFormat
							.format(ConnectionView.this.date)
							+ " "
							+ "Connection is closed. \n";
					ConnectionView.this.createMessageLog("Disabled", null,
							false);
				}
			}
		});
	}

	private void addGeneralInfo() {
		// ------------------------ Group general---------------------
		/*
		 * Group groupGeneral = new Group(this.sectionClient, SWT.NONE);
		 * groupGeneral.setText("General");
		 * 
		 * // Set layout for the group this.gridLayoutCommon = new GridLayout();
		 * this.gridLayoutCommon.numColumns = this.numCols;
		 * 
		 * GridData gridData = new GridData(GridData.FILL_VERTICAL);
		 * gridData.horizontalSpan = this.numCols;
		 * 
		 * groupGeneral.setLayout(this.gridLayoutCommon);
		 * groupGeneral.setLayoutData(gridData);
		 */

		this.toolkit.createLabel(this.sectionClient, "Protocol:")
				.setLayoutData(this.gridDataLabel);
		this.comboProtocol = new Combo(this.sectionClient, SWT.READ_ONLY
				| SWT.DROP_DOWN);
		this.comboProtocol.setLayoutData(this.gridDataText);
		this.comboProtocol.setItems(this.strProtocolData);
		this.comboProtocol.select(0);
		this.comboProtocol.setEnabled(true);

		this.toolkit.createLabel(this.sectionClient, "DeviceID:")
				.setLayoutData(this.gridDataLabel);
		this.textDeviceID = this.toolkit.createText(this.sectionClient, "",
				SWT.SINGLE);
		this.textDeviceID.setLayoutData(this.gridDataText);

		this.toolkit.createLabel(this.sectionClient, "Type:").setLayoutData(
				this.gridDataLabel);
		this.comboType = new Combo(this.sectionClient, SWT.READ_ONLY
				| SWT.DROP_DOWN);
		this.comboType.setLayoutData(this.gridDataText);
		this.comboType.setItems(this.strTypeData);

		this.toolkit.createLabel(this.sectionClient, "T3 (sec):")
				.setLayoutData(this.gridDataLabel);
		this.textT3 = this.toolkit.createText(this.sectionClient, "",
				SWT.SINGLE);
		this.textT3.setLayoutData(this.gridDataText);
	}

	private void addHSMSInfo() {

		GridData gridData;
		int groupCols = this.numCols / 2;

		// ----------------------------------------------------------
		// ---------------------- Group HSMS -----------------------
		// Set data for the group
		Group groupHSMS = new Group(this.sectionClient, SWT.NONE);
		groupHSMS.setText("HSMS-SECSI");

		// Set layout for the group
		this.gridLayoutCommon = new GridLayout();
		this.gridLayoutCommon.numColumns = this.numCols;

		gridData = new GridData(GridData.FILL_VERTICAL);
		gridData.horizontalSpan = this.numCols;

		groupHSMS.setLayout(this.gridLayoutCommon);
		groupHSMS.setLayoutData(gridData);

		// ----------------------------------------------------------
		// ---------------- Set layout for all group -----------------
		this.gridLayoutCommon = new GridLayout();
		this.gridLayoutCommon.numColumns = groupCols;

		// ----------------------------------------------------------
		// ---------------- Group Empty -----------------
		gridData = new GridData(GridData.VERTICAL_ALIGN_BEGINNING);
		gridData.horizontalSpan = 2;

		Group groupEmpty = new Group(groupHSMS, SWT.NONE);
		groupEmpty.setLayout(this.gridLayoutCommon);
		groupEmpty.setLayoutData(gridData);

		// ----------------------------------------------------------
		// ---------------- Group Message Response -----------------
		Group groupMesRespone = new Group(groupEmpty, SWT.NONE);
		groupMesRespone.setText("Message Response");

		gridData = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
		gridData.horizontalSpan = groupCols;

		groupMesRespone.setLayout(this.gridLayoutCommon);
		groupMesRespone.setLayoutData(gridData);

		this.radioManual = new Button(groupMesRespone, SWT.RADIO);
		this.radioManual.setText("Manual");
		this.radioManual.setLayoutData(this.gridDataLabelGroup);

		this.radioAuto = new Button(groupMesRespone, SWT.RADIO);
		this.radioAuto.setText("Automatic");
		this.radioAuto.setLayoutData(this.gridDataLabelGroup);

		// ----------------------------------------------------------
		// ----------------- Group Connect Mode --------------------
		Group groupConnectMode = new Group(groupEmpty, SWT.NONE);
		groupConnectMode.setText("Connect Mode");

		gridData = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
		gridData.horizontalSpan = groupCols;

		groupConnectMode.setLayout(this.gridLayoutCommon);
		groupConnectMode.setLayoutData(gridData);

		this.radioActive = new Button(groupConnectMode, SWT.RADIO);
		this.radioActive.setText("Active");
		this.radioActive.setLayoutData(this.gridDataLabelGroup);

		this.radioPassive = new Button(groupConnectMode, SWT.RADIO);
		this.radioPassive.setText("Passive");
		this.radioPassive.setLayoutData(this.gridDataLabelGroup);

		// ----------------------------------------------------------
		// -------------------- Group Address ----------------------
		Group groupAddress = new Group(groupEmpty, SWT.NONE);
		groupAddress.setText("Connect Mode");

		gridData = new GridData();
		gridData.horizontalSpan = groupCols;

		groupAddress.setLayout(this.gridLayoutCommon);
		groupAddress.setLayoutData(gridData);

		this.toolkit.createLabel(groupAddress, "IP Address:").setLayoutData(
				this.gridDataLabelGroup);
		this.textIPAddress = this.toolkit
				.createText(groupAddress, "", SWT.NONE);
		this.textIPAddress.setLayoutData(this.gridDataTextGroup);

		this.toolkit.createLabel(groupAddress, "Port:").setLayoutData(
				this.gridDataLabelGroup);
		this.textPort = this.toolkit.createText(groupAddress, "", SWT.NONE);
		this.textPort.setLayoutData(this.gridDataTextGroup);

		// --------get available comport-----------
		String[] listPort = readAvailablePort();

		this.toolkit.createLabel(groupAddress, "Com Port:").setLayoutData(
				this.gridDataLabelGroup);
		this.comboComport = new Combo(groupAddress, SWT.READ_ONLY
				| SWT.DROP_DOWN);
		this.comboComport.setLayoutData(this.gridDataTextGroup);
		this.comboComport.setItems(listPort);
		this.comboComport.select(0);
		this.comboProtocol.setEnabled(true);

		// ----------------------------------------------------------
		// -------------------- Group Timeout ----------------------
		Group groupTimeout = new Group(groupHSMS, SWT.NONE);
		groupTimeout.setText("Timeout");

		// Set layout for the group
		this.gridLayoutCommon = new GridLayout();
		this.gridLayoutCommon.numColumns = groupCols;
		this.gridLayoutCommon.verticalSpacing = 5;
		this.gridLayoutCommon.marginTop = 5;

		gridData = new GridData(GridData.VERTICAL_ALIGN_FILL);
		gridData.horizontalSpan = groupCols;

		groupTimeout.setLayout(this.gridLayoutCommon);
		groupTimeout.setLayoutData(gridData);

		this.toolkit.createLabel(groupTimeout, "T1 (sec):").setLayoutData(
				this.gridDataLabelGroup);
		this.textT1 = this.toolkit.createText(groupTimeout, "", SWT.NONE);
		this.textT1.setLayoutData(this.gridDataTextGroup);

		this.toolkit.createLabel(groupTimeout, "T2 (sec):").setLayoutData(
				this.gridDataLabelGroup);
		this.textT2 = this.toolkit.createText(groupTimeout, "", SWT.NONE);
		this.textT2.setLayoutData(this.gridDataTextGroup);

		this.toolkit.createLabel(groupTimeout, "T4 (sec):").setLayoutData(
				this.gridDataLabelGroup);
		this.textT4 = this.toolkit.createText(groupTimeout, "", SWT.NONE);
		this.textT4.setLayoutData(this.gridDataTextGroup);

		this.toolkit.createLabel(groupTimeout, "T5 (sec):").setLayoutData(
				this.gridDataLabelGroup);
		this.textT5 = this.toolkit.createText(groupTimeout, "", SWT.NONE);
		this.textT5.setLayoutData(this.gridDataTextGroup);

		this.toolkit.createLabel(groupTimeout, "T6 (sec):").setLayoutData(
				this.gridDataLabelGroup);
		this.textT6 = this.toolkit.createText(groupTimeout, "", SWT.NONE);
		this.textT6.setLayoutData(this.gridDataTextGroup);

		this.toolkit.createLabel(groupTimeout, "T7 (sec):").setLayoutData(
				this.gridDataLabelGroup);
		this.textT7 = this.toolkit.createText(groupTimeout, "", SWT.NONE);
		this.textT7.setLayoutData(this.gridDataTextGroup);

		this.toolkit.createLabel(groupTimeout, "T8 (sec):").setLayoutData(
				this.gridDataLabelGroup);
		this.textT8 = this.toolkit.createText(groupTimeout, "", SWT.NONE);
		this.textT8.setLayoutData(this.gridDataTextGroup);

		this.toolkit.createLabel(groupTimeout, "Linktest (sec):")
				.setLayoutData(this.gridDataLabelGroup);
		this.textLinktest = this.toolkit.createText(groupTimeout, "", SWT.NONE);
		this.textLinktest.setLayoutData(this.gridDataTextGroup);

	}

	private void addSectionHeader() {
		this.tableLayout = new TableWrapLayout(); // Create table wrap layout
		// for the section
		this.tableLayout.numColumns = this.numCols;

		this.tableData = new TableWrapData(TableWrapData.FILL_GRAB); // Create
		// table
		// wrap
		// data
		// for
		// section
		this.tableData.colspan = this.numCols;

		this.section = this.toolkit.createSection(this.scrolledForm.getBody(),
				Section.TITLE_BAR);
		this.section.setLayout(this.tableLayout); // Set layout and layout data
		// for section
		this.section.setLayoutData(this.tableData);
		this.section.setText("Connection Setting");

		this.sectionClient = this.toolkit.createComposite(this.section); // Create
		// the
		// composite
		// controls
		// keep
		// the
		// kinds
		// of
		// other
		// controls.
		GridLayout gridLayout = new GridLayout(this.numCols, false);
		this.sectionClient.setLayout(gridLayout);
		this.section.setClient(this.sectionClient);
	}

	private void convertFileToString(final File requiredFile) {
		StringBuffer buffer = new StringBuffer();
		String text;
		try {
			FileReader reader = new FileReader(requiredFile);
			LineNumberReader lineReader = new LineNumberReader(reader);

			do {
				text = lineReader.readLine();

				if (text != null) {
					buffer.append(text);
				}
			} while (text != null);

			this.strConfig = buffer.toString();
		} catch (FileNotFoundException ex) {
			ex.printStackTrace();
		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}

	private void createDevice() {
		device = new Device(this.strDeviceName, this);
		device.Configure(this.strConfig);
		device.Open();
	}

	private void createGridData() {
		this.gridDataText = new GridData(GridData.BEGINNING, GridData.CENTER,
				false, false);
		this.gridDataText.widthHint = 90;
		this.gridDataText.heightHint = 15;
		this.gridDataText.horizontalIndent = 2;

		this.gridDataLabel = new GridData(GridData.BEGINNING, GridData.CENTER,
				false, false);
		this.gridDataLabel.widthHint = 90;
		this.gridDataLabel.heightHint = 15;
		this.gridDataLabel.horizontalIndent = 25;
	}

	private void createGridDataGroup() {
		this.gridDataTextGroup = new GridData(GridData.BEGINNING,
				GridData.CENTER, false, false);
		this.gridDataTextGroup.widthHint = 90;
		this.gridDataTextGroup.heightHint = 15;

		this.gridDataLabelGroup = new GridData(GridData.BEGINNING,
				GridData.CENTER, false, false);
		this.gridDataLabelGroup.widthHint = 90;
		this.gridDataLabelGroup.heightHint = 15;
	}

	public void createMessageLog() {
		this.createMessageLog(this.strLogType, this.objMessage,
				this.isDataMessage);
	}

	private void createMessageLog(final String type, final Object secsMessage,
			final boolean isDataMessage) {
		switch (type) {
		case "RECV":
		case "SENT":
		case "UNKO":
		case "INIT":
		case "TIMO":
			if (isDataMessage) {
				this.secsMessage = (SECSMessage) secsMessage;
				this.messageLog += this.secsMessage.Name();
				this.messageLog += (this.secsMessage.WaitBit()) ? " W" : " ";
				this.messageLog += " sysbyte=0x"
						+ Long.toHexString(this.secsMessage.SystemBytes());
				this.messageLog += " length=" + (this.secsMessage.Length());
				this.messageLog += " deviceID=" + this.secsMessage.DeviceID()
						+ "\r\n";
				this.messageLog += "HEX FORMAT:\r\n"
						+ this.secsMessage.ToString() + "\r\n";
				this.messageLog += "SML:\r\n" + this.secsMessage.ToSml()
						+ "\r\n";
			} else {
				this.hsmsMessage = (HSMSMessage) secsMessage;
				switch (this.hsmsMessage.SType()) {
				case HSMSMessageType.SelReq:
					this.messageLog += "Select.req";
					break;
				case HSMSMessageType.SelRes:
					this.messageLog += "Select.rsp";
					break;
				case HSMSMessageType.DeSelReq:
					this.messageLog += "Deselect.req";
					break;
				case HSMSMessageType.DeSelRes:
					this.messageLog += "Deselect.rsp";
					break;
				case HSMSMessageType.LinkTestReq:
					this.messageLog += "Linktest.req";
					break;
				case HSMSMessageType.LinkTestRes:
					this.messageLog += "Linktest.rsp";
					break;
				case HSMSMessageType.RejectReq:
					this.messageLog += "Reject.req";
					break;
				case HSMSMessageType.RejectRes:
					this.messageLog += "Reject.rsp";
					break;
				case HSMSMessageType.SeparateReq:
					this.messageLog += "Separate.req";
					break;
				}
				;

				this.messageLog += " sysbyte=0x"
						+ Long.toHexString(this.hsmsMessage.SystemBytes());
				this.messageLog += " length=" + this.hsmsMessage.Length()
						+ "\r\n";
				this.messageLog += "HEX FORMAT:\r\n"
						+ this.hsmsMessage.ToString() + "\r\n";
			}

			this.writeWindows(type, this.messageLog);
			break;
		default:
			this.writeWindows(type, this.messageLog);
			break;
		}
	}

	/**
	 * This is a call back that will allow us to create the viewer and
	 * initialize it.
	 */
	@Override
	public void createPartControl(final Composite parent) {
		// Create a Form API toolkit
		this.toolkit = new FormToolkit(parent.getDisplay());

		/**
		 * Create a scrolled form widget in the provided parent. If you do not
		 * require scrolling because there is already a scrolled composite up
		 * the parent chain, use 'createForm' instead
		 */
		this.scrolledForm = this.toolkit.createScrolledForm(parent);

		/**
		 * Takes advantage of the gradients and other capabilities to decorate
		 * the form heading using colors computed based on the current skin and
		 * operating system.
		 */
		this.toolkit.decorateFormHeading(this.scrolledForm.getForm());

		// Add a 1 column layout to the scrolled form contents
		TableWrapLayout layout = new TableWrapLayout();
		layout.numColumns = this.numCols;

		this.scrolledForm.getBody().setLayout(layout);

		// Create grid data
		this.createGridData();
		this.createGridDataGroup();

		/**
		 * Add controls
		 */
		this.addSectionHeader();
		this.addGeneralInfo();
		this.addHSMSInfo();
		this.addButton();
		this.createStyleRange();

		/**
		 * Load data from the configured file
		 */
		this.loadConfig();
	}

	private void createStyleRange() {
		// create the font
		Font font = new Font(Display.getDefault(), "Tahoma", 10, SWT.NORMAL);

		// make the style standard
		this.styleStandar = new StyleRange();
		this.styleStandar.font = font;
		this.styleStandar.foreground = Display.getDefault().getSystemColor(
				SWT.COLOR_BLACK);

		// make the style received message
		this.styleReceived = new StyleRange();
		this.styleReceived.font = font;
		this.styleReceived.foreground = Display.getDefault().getSystemColor(
				SWT.COLOR_DARK_GREEN);

		// make the style send message
		this.styleSend = new StyleRange();
		this.styleSend.font = font;
		this.styleSend.foreground = Display.getDefault().getSystemColor(
				SWT.COLOR_BLUE);

		// make the style error message
		this.styleError = new StyleRange();
		this.styleError.font = font;
		this.styleError.foreground = Display.getDefault().getSystemColor(
				SWT.COLOR_RED);
	}

	/**
	 * This method is used to get the colors and toolkit management.
	 * 
	 * @param display
	 *            the object is required to get the colors.
	 * @return an object of FormColors class
	 */
	public FormColors getFromColors(final Display display) {
		final Color COLOR_START = new Color(null, 128, 128, 128);
		final Color COLOR_END = new Color(null, 255, 255, 255);
		final Color COLOR_HEADING = new Color(null, 102, 102, 102);

		FormColors formColors;

		formColors = new FormColors(display);

		formColors.createColor(IFormColors.H_GRADIENT_START,
				COLOR_START.getRGB());
		formColors.createColor(IFormColors.H_GRADIENT_END, COLOR_END.getRGB());
		formColors.createColor(IFormColors.H_BOTTOM_KEYLINE1,
				COLOR_END.getRGB());
		formColors.createColor(IFormColors.H_BOTTOM_KEYLINE2,
				COLOR_START.getRGB());
		formColors.createColor(IFormColors.TITLE, COLOR_HEADING.getRGB());

		return formColors;
	}

	public String getLogDir() {
		return this.strLogDir;
	}

	@Override
	public void handleEvent(final Event event) {
		System.out.println(event);
	}

	@Override
	public short ID() {
		return 0;
	}

	@Override
	public void ID(final short id) {
	}

	private void loadConfig() {
		try {
			URL fileURL = FileLocator.find(Platform
					.getBundle("SECSTestApplication"), new Path(
					"/configs/configure.xml"), null);
			fileURL = FileLocator.toFileURL(fileURL);
			this.strFileName = fileURL.getPath();

			File fileConfigure = new File(this.strFileName);

			if (fileConfigure.exists()) {
				DocumentBuilderFactory dbFactory = DocumentBuilderFactory
						.newInstance();
				DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
				this.docConfig = dBuilder.parse(fileConfigure);
				this.docConfig.getDocumentElement().normalize();

				if (this.docConfig != null) {
					this.readConfig(this.docConfig);
				}

				this.convertFileToString(fileConfigure);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	@Override
	public String Name() {
		return null;
	}

	@Override
	public void Name(final String value) {
	}

	@Override
	public void OnAction(String message) {

		this.date = new Date();
		// if (error.Type() == SECSErrorType.Exception) {
		this.messageLog = this.dateFormat.format(this.date) + "  " + "INFO: "
				+ message + " \n";
		this.createMessageLog("INFO", message, true);
	}

	@Override
	public void OnCommunicationDisabled() {
		this.date = new Date();
		this.messageLog = this.dateFormat.format(this.date)
				+ " Connection is closed. \n";

		this.setLogParameters("Disabled", null, false);
	}

	@Override
	public void OnCommunicationEnabled() {
		this.date = new Date();
		this.messageLog = this.dateFormat.format(this.date)
				+ " Communication session opened. \n";

		this.setLogParameters("Enabled", null, false);
	}

	@Override
	public void OnConversationTimeout(final Object message) {
		this.date = new Date();
		this.messageLog = this.dateFormat.format(this.date) + "T3 Timeout on ";

		this.setLogParameters("TIMO", message, true);
	}

	@Override
	public void OnError(final Object message) {
		this.date = new Date();
		SECSError error = (SECSError) message;
		// if (error.Type() == SECSErrorType.Exception) {
		this.messageLog = this.dateFormat.format(this.date) + "  " + "ERROR: "
				+ error.Message() + " \n";
		this.createMessageLog("ERROR", message, true);
		// }
	}

	@Override
	public void OnInitialized(final Object message) {
		this.date = new Date();
		this.messageLog = this.dateFormat.format(this.date) + "  " + "INIT: ";

		this.setLogParameters("INIT", message, true);
	}

	@Override
	public void OnMessageReceived(final Object message) {
		this.date = new Date();
		this.messageLog = this.dateFormat.format(this.date) + "  " + "RECV: ";

		this.setLogParameters("RECV", message, true);

		if (isAuto) {

			SECSMessage primaryMsg = (SECSMessage) message;
			SECSMessage secondaryMsg = device.GetSECSMessage(
					primaryMsg.StreamNumber(), primaryMsg.FunctionNumber() + 1);

			if (secondaryMsg != null) {
				device.Reply(secondaryMsg, primaryMsg);
			}
		}
	}

	@Override
	public void OnMessageSent(final Object message) {
		this.date = new Date();
		this.messageLog = this.dateFormat.format(this.date) + "  " + "SENT: ";

		this.setLogParameters("SENT", message, true);

	}

	@Override
	public void OnTimeout(final Object message) {

		SecsTimeout secsTimeout = (SecsTimeout) message;
		this.date = new Date();
		this.messageLog = this.dateFormat.format(this.date) + " "
				+ secsTimeout.Message() + "\n";

		this.setLogParameters("TIMO@", null, false);
	}

	@Override
	public void OnUnknownMessage(final Object message) {
		this.date = new Date();
		this.messageLog = this.dateFormat.format(this.date) + "  " + "UNKO: ";

		this.setLogParameters("UNKO", message, true);
	}

	private String[] readAvailablePort() {

		@SuppressWarnings("rawtypes")
		Enumeration ports = CommPortIdentifier.getPortIdentifiers();

		List<String> portNames = new ArrayList<String>();
		while (ports.hasMoreElements()) {
			portNames.add(((CommPortIdentifier) ports.nextElement()).getName());
		}

		String[] listPort = new String[portNames.size()];
		for (int i = 0; i < portNames.size(); i++) {
			listPort[i] = portNames.get(i);
		}

		return listPort;
	}

	private boolean readConfig(final Document doc) {
		String value = "";
		NodeList xmlDeviceList = doc.getElementsByTagName("device");
		if (xmlDeviceList != null) {
			for (int index = 0; index < xmlDeviceList.getLength(); index++) {
				Node xmlDevice = xmlDeviceList.item(index);

				if (xmlDevice.hasAttributes()) {
					this.textDeviceID.setText(xmlDevice.getAttributes()
							.getNamedItem("id").getNodeValue());
					this.strDeviceID = xmlDevice.getAttributes()
							.getNamedItem("deviceID").getNodeValue();
					this.strDeviceName = xmlDevice.getAttributes()
							.getNamedItem("name").getNodeValue();
					this.strPortName = xmlDevice.getAttributes()
							.getNamedItem("port").getNodeValue();

				}
			}
		}

		NodeList xmlPortList = doc.getElementsByTagName("port");
		if (xmlPortList != null) {
			for (int index = 0; index < xmlPortList.getLength(); index++) {
				Node xmlPort = xmlPortList.item(index);

				if (xmlPort.hasAttributes()) {
					value = xmlPort.getAttributes().getNamedItem("name")
							.getNodeValue();
					if (value.equalsIgnoreCase(this.strPortName)) {
						value = xmlPort.getAttributes().getNamedItem("active")
								.getNodeValue();
						if (value.equals("Y")) {
							this.radioActive.setSelection(true);
						} else {
							this.radioPassive.setSelection(true);
						}

						value = xmlPort.getAttributes().getNamedItem("isAuto")
								.getNodeValue();
						if (value.equals("Y")) {
							this.radioAuto.setSelection(true);
							isAuto = true;
						} else {
							this.radioManual.setSelection(true);
							isAuto = false;
						}

						value = xmlPort.getAttributes().getNamedItem("server")
								.getNodeValue();
						if (value != "") {
							this.textIPAddress.setText(value);
						} else {
							this.textIPAddress.setText("localhost");
						}

						value = xmlPort.getAttributes().getNamedItem("port")
								.getNodeValue();
						if (value != "") {
							this.textPort.setText(value);
						} else {
							this.textPort.setText("");
						}

						value = xmlPort.getAttributes()
								.getNamedItem("protocol").getNodeValue();
						if (value.equalsIgnoreCase("HSMS")) {
							this.comboProtocol.select(0);
						} else {
							this.comboProtocol.select(1);
						}

						value = xmlPort.getAttributes().getNamedItem("comPort")
								.getNodeValue();

						for (int i = 0; i < comboComport.getItemCount(); i++) {
							if (comboComport.getItem(i).toString()
									.equals(value)) {
								this.comboComport.select(i);
							}
						}

						value = xmlPort.getAttributes().getNamedItem("T1")
								.getNodeValue();
						value = String
								.valueOf((Float.parseFloat(value) / 1000));
						if (value != "") {
							this.textT1.setText(value);
						} else {
							this.textT1.setText("45");
						}

						value = xmlPort.getAttributes().getNamedItem("T2")
								.getNodeValue();
						value = String
								.valueOf((Float.parseFloat(value) / 1000));
						if (value != "") {
							this.textT2.setText(value);
						} else {
							this.textT2.setText("45");
						}

						value = xmlPort.getAttributes().getNamedItem("T3")
								.getNodeValue();
						value = String
								.valueOf((Integer.parseInt(value) / 1000));
						if (value != "") {
							this.textT3.setText(value);
						} else {
							this.textT3.setText("45");
						}

						value = xmlPort.getAttributes().getNamedItem("T4")
								.getNodeValue();
						value = String
								.valueOf((Integer.parseInt(value) / 1000));
						if (value != "") {
							this.textT4.setText(value);
						} else {
							this.textT4.setText("0");
						}

						value = xmlPort.getAttributes()
								.getNamedItem("linkTest").getNodeValue();
						value = String
								.valueOf((Integer.parseInt(value) / 1000));
						if (value != "") {
							this.textLinktest.setText(value);
						} else {
							this.textLinktest.setText("0");
						}

						value = xmlPort.getAttributes().getNamedItem("T5")
								.getNodeValue();
						value = String
								.valueOf((Integer.parseInt(value) / 1000));
						if (value != "") {
							this.textT5.setText(value);
						} else {
							this.textT5.setText("10");
						}

						value = xmlPort.getAttributes().getNamedItem("T6")
								.getNodeValue();
						value = String
								.valueOf((Integer.parseInt(value) / 1000));
						if (value != "") {
							this.textT6.setText(value);
						} else {
							this.textT6.setText("5");
						}

						value = xmlPort.getAttributes().getNamedItem("T7")
								.getNodeValue();
						value = String
								.valueOf((Integer.parseInt(value) / 1000));
						if (value != "") {
							this.textT7.setText(value);
						} else {
							this.textT7.setText("10");
						}

						value = xmlPort.getAttributes().getNamedItem("T8")
								.getNodeValue();
						value = String
								.valueOf((Integer.parseInt(value) / 1000));
						if (value != "") {
							this.textT8.setText(value);
						} else {
							this.textT8.setText("5");
						}

						value = xmlPort.getAttributes().getNamedItem("logdir")
								.getNodeValue();
						if (value != "") {
							this.strLogDir = value;
						}

						value = xmlPort.getAttributes().getNamedItem("master")
								.getNodeValue();
						if (value.equalsIgnoreCase("Y")) {
							this.comboType.select(0);
						} else {
							this.comboType.select(1);
						}
					}
				}
			}
			return true;
		}
		return false;
	}

	/**
	 * Passing the focus request to the viewer's control.
	 */
	@Override
	public void setFocus() {
		this.scrolledForm.setFocus();
	}

	public void setLogParameters(final String logType, final Object message,
			final boolean isDataMessage) {
		this.strLogType = logType;
		this.objMessage = message;
		this.isDataMessage = isDataMessage;

		this.createMessageLog();
	}

	/*
	 * @Override public void OnConnecting(final Object message) { this.date =
	 * new Date(); this.messageLog = this.dateFormat.format(this.date) + " " +
	 * message;
	 * 
	 * this.setLogParameters("CONT", null, false); }
	 * 
	 * @Override public void OnHSMSReceived(final Object message) { this.date =
	 * new Date(); this.messageLog = this.dateFormat.format(this.date) +
	 * " RECV: ";
	 * 
	 * this.setLogParameters("RECV", message, false); }
	 * 
	 * @Override public void OnHSMSSent(final Object message) { this.date = new
	 * Date(); this.messageLog = this.dateFormat.format(this.date) + " SENT: ";
	 * 
	 * this.setLogParameters("SENT", message, false); }
	 * 
	 * @Override public void OnListening(final Object message) { this.date = new
	 * Date(); this.messageLog = this.dateFormat.format(this.date) + " " +
	 * message;
	 * 
	 * this.setLogParameters("LIST", null, false); }
	 */

	private boolean writeConfig(final Document doc) {
		String value = "";
		NodeList xmlDeviceList = doc.getElementsByTagName("device");

		if (xmlDeviceList != null && xmlDeviceList.getLength() > 0) {
			for (int index = 0; index < xmlDeviceList.getLength(); index++) {
				Node xmlDevice = xmlDeviceList.item(index);

				if (xmlDevice.hasAttributes()) {
					value = xmlDevice.getAttributes().getNamedItem("deviceID")
							.getNodeValue();

					if (value.equalsIgnoreCase(this.strDeviceID)) {
						xmlDevice.getAttributes().getNamedItem("name")
								.setNodeValue(this.strDeviceName);
						xmlDevice.getAttributes().getNamedItem("id")
								.setNodeValue(this.textDeviceID.getText());
						xmlDevice.getAttributes().getNamedItem("port")
								.setNodeValue(this.strPortName);
					}
				}
			}
		}

		NodeList xmlPortList = doc.getElementsByTagName("port");

		if (xmlPortList != null && xmlPortList.getLength() > 0) {
			for (int index = 0; index < xmlPortList.getLength(); index++) {
				Node xmlPort = xmlPortList.item(index);

				if (xmlPort.hasAttributes()) {
					value = xmlPort.getAttributes().getNamedItem("name")
							.getNodeValue();

					if (value.equalsIgnoreCase(this.strPortName)) {

						// Set connect mode
						if (this.radioActive.getSelection()) {
							xmlPort.getAttributes().getNamedItem("active")
									.setNodeValue("Y");
						} else {
							xmlPort.getAttributes().getNamedItem("active")
									.setNodeValue("N");
						}

						// Set ip address
						xmlPort.getAttributes().getNamedItem("server")
								.setNodeValue(this.textIPAddress.getText());

						// Set port
						xmlPort.getAttributes().getNamedItem("port")
								.setNodeValue(this.textPort.getText());

						// Set protocol
						xmlPort.getAttributes().getNamedItem("protocol")
								.setNodeValue(this.comboProtocol.getText());

						// Set COM port
						xmlPort.getAttributes().getNamedItem("comPort")
								.setNodeValue(this.comboComport.getText());

						// Set T1 timeout
						value = String.valueOf(Float.parseFloat(this.textT1
								.getText()) * 1000);
						xmlPort.getAttributes().getNamedItem("T1")
								.setNodeValue(value);

						// Set T2 timeout
						value = String.valueOf(Float.parseFloat(this.textT2
								.getText()) * 1000);
						xmlPort.getAttributes().getNamedItem("T2")
								.setNodeValue(value);

						// Set T3 timeout
						value = String.valueOf(Integer.parseInt(this.textT3
								.getText()) * 1000);
						xmlPort.getAttributes().getNamedItem("T3")
								.setNodeValue(value);

						// Set T4 timeout
						value = String.valueOf(Integer.parseInt(this.textT4
								.getText()) * 1000);
						xmlPort.getAttributes().getNamedItem("T4")
								.setNodeValue(value);

						// Set Link-test timer
						value = String.valueOf(Integer
								.parseInt(this.textLinktest.getText()) * 1000);
						xmlPort.getAttributes().getNamedItem("linkTest")
								.setNodeValue(value);

						// Set T5 timeout
						value = String.valueOf(Integer.parseInt(this.textT5
								.getText()) * 1000);
						xmlPort.getAttributes().getNamedItem("T5")
								.setNodeValue(value);

						// Set T6 timeout
						value = String.valueOf(Integer.parseInt(this.textT6
								.getText()) * 1000);
						xmlPort.getAttributes().getNamedItem("T6")
								.setNodeValue(value);

						// Set T7 timeout
						value = String.valueOf(Integer.parseInt(this.textT7
								.getText()) * 1000);
						xmlPort.getAttributes().getNamedItem("T7")
								.setNodeValue(value);

						// Set T8 timeout
						value = String.valueOf(Integer.parseInt(this.textT8
								.getText()) * 1000);
						xmlPort.getAttributes().getNamedItem("T8")
								.setNodeValue(value);

						// Set message response
						if (this.radioAuto.getSelection()) {
							xmlPort.getAttributes().getNamedItem("isAuto")
									.setNodeValue("Y");
							isAuto = true;
						} else {
							xmlPort.getAttributes().getNamedItem("isAuto")
									.setNodeValue("N");
							isAuto = false;
						}

						if (this.comboType.getText().equalsIgnoreCase("Host")) {
							xmlPort.getAttributes().getNamedItem("master")
									.setNodeValue("N");
						} else {
							xmlPort.getAttributes().getNamedItem("master")
									.setNodeValue("Y");
						}
					}
				}
			}
			doc.normalizeDocument();
			return true;
		}

		return false;
	}

	/*
	 * @Override public void OnHSMSState(final Object message) { this.date = new
	 * Date(); this.messageLog = this.dateFormat.format(this.date) + " " +
	 * message + "\n";
	 * 
	 * this.setLogParameters("STAT@", null, false); }
	 */

	private boolean writeFileConfig(final Document doc) {
		try {
			// write the content into xml file
			TransformerFactory transformerFactory = TransformerFactory
					.newInstance();
			Transformer transformer = transformerFactory.newTransformer();
			DOMSource source = new DOMSource(doc);
			StreamResult result = new StreamResult(new File(this.strFileName));
			transformer.transform(source, result);

			return true;

		} catch (TransformerException ex) {
			ex.printStackTrace();
			return false;
		}
	}

	private void writeLog() {
		try {
			// Create file
			FileWriter fstream = new FileWriter(this.strLogDir + "/"
					+ this.strDeviceName + ".log", true);
			BufferedWriter out = new BufferedWriter(fstream);
			out.write(this.messageLog);

			// Close the output stream
			out.close();
		} catch (Exception e) {
			// Catch exception if any
			e.printStackTrace();
		}
	}

	private void writeWindows(final String type, final String message) {
		if (!LogView.textLog.isDisposed()) {
			LogView.textLog.getDisplay().syncExec(new Runnable() {
				@Override
				public void run() {
					int logLength = LogView.textLog.getText().length();

					LogView.textLog.append(ConnectionView.this.messageLog);

					switch (type) {
					case "RECV":
						ConnectionView.this.styleReceived.start = logLength;
						ConnectionView.this.styleReceived.length = message
								.length();
						LogView.textLog
								.setStyleRange(ConnectionView.this.styleReceived);
						break;
					case "SENT":
						ConnectionView.this.styleSend.start = logLength;
						ConnectionView.this.styleSend.length = message.length();
						LogView.textLog
								.setStyleRange(ConnectionView.this.styleSend);
						break;
					case "ERROR":
					case "TIMO":
					case "TIMO@":
						ConnectionView.this.styleError.start = logLength;
						ConnectionView.this.styleError.length = message
								.length();
						LogView.textLog
								.setStyleRange(ConnectionView.this.styleError);
						break;
					default:
						ConnectionView.this.styleStandar.start = logLength;
						ConnectionView.this.styleStandar.length = message
								.length();
						LogView.textLog
								.setStyleRange(ConnectionView.this.styleStandar);
						break;
					}
				}
			});
		}

		this.writeLog();
	}
}
